bitkeeper revision 1.1389.15.13 (42821f23dLMLc5Ql8Y-rUwoatYBI6g)
authorcl349@firebug.cl.cam.ac.uk[cl349] <cl349@firebug.cl.cam.ac.uk[cl349]>
Wed, 11 May 2005 15:05:07 +0000 (15:05 +0000)
committercl349@firebug.cl.cam.ac.uk[cl349] <cl349@firebug.cl.cam.ac.uk[cl349]>
Wed, 11 May 2005 15:05:07 +0000 (15:05 +0000)
Split out context fetching into separate DOM0 op
make GETDOMAININFO a little more sensible with respect to MP
make coredump dump all cpu contexts
Signed-off-by: Kip Macy <kmacy@netapp.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
12 files changed:
tools/libxc/xc.h
tools/libxc/xc_core.c
tools/libxc/xc_domain.c
tools/libxc/xc_linux_build.c
tools/libxc/xc_linux_restore.c
tools/libxc/xc_linux_save.c
tools/libxc/xc_plan9_build.c
tools/libxc/xc_private.c
tools/libxc/xc_ptrace.c
tools/libxc/xc_vmx_build.c
xen/common/dom0_ops.c
xen/include/public/dom0_ops.h

index 68a1fb6abc53c88f359464cb99ae106ebdacb8b3..b02426d5eaff7f981f629bf789ea5f9667c3b810 100644 (file)
@@ -110,8 +110,10 @@ int xc_waitdomain_core(int domain,
 
 typedef struct {
     u32           domid;
-    unsigned int  cpu;
+    unsigned int  flags;
+    unsigned int  processors;
     unsigned int  vcpus;
+    u16           n_vcpus;     
     unsigned int  dying:1, crashed:1, shutdown:1, 
                   paused:1, blocked:1, running:1;
     unsigned int  shutdown_reason; /* only meaningful if shutdown==1 */
@@ -199,11 +201,11 @@ int xc_domain_getinfo(int xc_handle,
  *            domain
  * @return 0 on success, -1 on failure
  */
-int xc_domain_getfullinfo(int xc_handle,
-                          u32 domid,
-                          u32 vcpu,
-                          xc_domaininfo_t *info,
-                          vcpu_guest_context_t *ctxt);
+int xc_domain_get_vcpu_context(int xc_handle,
+                             u32 domid,
+                             u32 vcpu,
+                             vcpu_guest_context_t *ctxt);
+
 int xc_domain_setcpuweight(int xc_handle,
                            u32 domid,
                            float weight);
index 84ef16bf3785d59e1611b3be4b1043df7f935673..50fe1c26aae93cc11d62b13f31642b4d79be3281 100644 (file)
@@ -7,6 +7,7 @@
 /* number of pages to write at a time */
 #define DUMP_INCREMENT 4 * 1024
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
+
 static int
 copy_from_domain_page(int xc_handle,
                      u32 domid,
@@ -28,13 +29,14 @@ xc_domain_dumpcore(int xc_handle,
                   u32 domid,
                   const char *corename)
 {
-       vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
        unsigned long nr_pages;
        unsigned long *page_array;
-       xc_domaininfo_t st_info, *info = &st_info;
+       xc_dominfo_t info;
        int i, dump_fd;
        char *dump_mem, *dump_mem_start = NULL;
        struct xc_core_header header;
+       vcpu_guest_context_t     ctxt[MAX_VIRT_CPUS];
+
        
        if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) {
                PERROR("Could not open corefile %s: %s", corename, strerror(errno));
@@ -46,14 +48,22 @@ xc_domain_dumpcore(int xc_handle,
                goto error_out;
        }
        
-       if (xc_domain_getfullinfo(xc_handle, domid, 0/* XXX hardcode */, info, ctxt)) {
-               PERROR("Could not get full info for domain");
+       if (xc_domain_getinfo(xc_handle, domid, 1, &info)) {
+               PERROR("Could not get info for domain");
                goto error_out;
        }
+       
+       for (i = 0; i < info.n_vcpus; i++) {
+               if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[i])) {
+                       PERROR("Could not get all vcpu contexts for domain");
+                       goto error_out;
+               }
+       }
+       
+       nr_pages = info.nr_pages;
 
-       nr_pages = info->tot_pages;
        header.xch_magic = 0xF00FEBED; 
-       header.xch_nr_vcpus = 1; /* no interface to query at the moment */
+       header.xch_nr_vcpus = info.n_vcpus;
        header.xch_nr_pages = nr_pages;
        header.xch_ctxt_offset = sizeof(struct xc_core_header);
        header.xch_index_offset = sizeof(struct xc_core_header) +
@@ -62,7 +72,7 @@ xc_domain_dumpcore(int xc_handle,
            sizeof(vcpu_guest_context_t) + nr_pages * sizeof(unsigned long));
 
        write(dump_fd, &header, sizeof(struct xc_core_header));
-       write(dump_fd, ctxt, sizeof(st_ctxt));
+       write(dump_fd, &ctxt, sizeof(ctxt[0]) * info.n_vcpus);
 
        if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
            printf("Could not allocate memory\n");
index 12a724b2f2c4e0b908e4ca29651db51cda28c84e..ac82bcffd24af9e05b9b53c6363f1ee3d60f944e 100644 (file)
@@ -112,14 +112,12 @@ int xc_domain_getinfo(int xc_handle,
     {
         op.cmd = DOM0_GETDOMAININFO;
         op.u.getdomaininfo.domain = (domid_t)next_domid;
-        op.u.getdomaininfo.exec_domain = 0; // FIX ME?!?
-        op.u.getdomaininfo.ctxt = NULL; /* no exec context info, thanks. */
         if ( (rc = do_dom0_op(xc_handle, &op)) < 0 )
             break;
-        info->domid   = (u16)op.u.getdomaininfo.domain;
-
-        info->cpu     =
-            (op.u.getdomaininfo.flags>>DOMFLAGS_CPUSHIFT) & DOMFLAGS_CPUMASK;
+        info->domid      = (u16)op.u.getdomaininfo.domain;
+        info->processors = op.u.getdomaininfo.processors;
+       info->n_vcpus    = op.u.getdomaininfo.n_active_vcpus;
+       info->flags      = op.u.getdomaininfo.flags;
 
         info->dying    = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING);
         info->crashed  = !!(op.u.getdomaininfo.flags & DOMFLAGS_CRASHED);
@@ -142,28 +140,27 @@ int xc_domain_getinfo(int xc_handle,
         memcpy(&info->cpumap, &op.u.getdomaininfo.cpumap, 
                sizeof(info->cpumap));
 
-        next_domid = (u16)op.u.getdomaininfo.domain + 1;
-        info++;
+       next_domid = (u16)op.u.getdomaininfo.domain + 1;
+       info++;
     }
 
-    if(!nr_doms) return rc; 
+    if( !nr_doms ) return rc; 
 
     return nr_doms;
 }
 
-int xc_domain_getfullinfo(int xc_handle,
-                          u32 domid,
-                          u32 vcpu,
-                          xc_domaininfo_t *info,
-                          vcpu_guest_context_t *ctxt)
+int xc_domain_get_vcpu_context(int xc_handle,
+                              u32 domid,
+                              u32 vcpu,
+                              vcpu_guest_context_t *ctxt)
 {
     int rc, errno_saved;
     dom0_op_t op;
 
-    op.cmd = DOM0_GETDOMAININFO;
-    op.u.getdomaininfo.domain = (domid_t)domid;
-    op.u.getdomaininfo.exec_domain = (u16)vcpu;
-    op.u.getdomaininfo.ctxt = ctxt;
+    op.cmd = DOM0_GETVCPUCONTEXT;
+    op.u.getvcpucontext.domain = (domid_t)domid;
+    op.u.getvcpucontext.exec_domain = (u16)vcpu;
+    op.u.getvcpucontext.ctxt = ctxt;
 
     if ( (ctxt != NULL) &&
          ((rc = mlock(ctxt, sizeof(*ctxt))) != 0) )
@@ -178,10 +175,7 @@ int xc_domain_getfullinfo(int xc_handle,
         errno = errno_saved;
     }
 
-    if ( info != NULL )
-        memcpy(info, &op.u.getdomaininfo, sizeof(*info));
-
-    if ( ((u16)op.u.getdomaininfo.domain != domid) && (rc > 0) )
+    if ( rc > 0 )
         return -ESRCH;
     else
         return rc;
index abf427f87fef8137c5acba41dd23511fc3fb4f3c..d5d344cfee032ea6450b514a6c95b542e733ff0d 100644 (file)
@@ -356,14 +356,19 @@ int xc_linux_build(int xc_handle,
 
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)domid;
-    op.u.getdomaininfo.exec_domain = 0;
-    op.u.getdomaininfo.ctxt = ctxt;
     if ( (do_dom0_op(xc_handle, &op) < 0) || 
          ((u16)op.u.getdomaininfo.domain != domid) )
     {
         PERROR("Could not get info on domain");
         goto error_out;
     }
+
+    if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
+    {
+        PERROR("Could not get vcpu context");
+        goto error_out;
+    }
+
     if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
          (ctxt->pt_base != 0) )
     {
index 3d3f4c1e186d5932202ec324d7f8f6417f5bfa85..6442e3926af2cdc7a2e9a3adc512f6c02ba52f7d 100644 (file)
@@ -181,8 +181,6 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
     /* Get the domain's shared-info frame. */
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)dom;
-    op.u.getdomaininfo.exec_domain = 0;
-    op.u.getdomaininfo.ctxt = NULL;
     if ( do_dom0_op(xc_handle, &op) < 0 )
     {
         xcio_error(ioctxt, "Could not get information on new domain");
index f8a28cf43f456e1667c9f2f8e5e15d68179c5ba2..43d12838ba6caea4d0520a1dfe1db7c62237695e 100644 (file)
@@ -324,7 +324,7 @@ static int analysis_phase( int xc_handle, u32 domid,
 
 
 int suspend_and_state(int xc_handle, XcIOContext *ioctxt,                    
-                      xc_domaininfo_t *info,
+                      xc_dominfo_t *info,
                       vcpu_guest_context_t *ctxt)
 {
     int i=0;
@@ -333,13 +333,18 @@ int suspend_and_state(int xc_handle, XcIOContext *ioctxt,
 
 retry:
 
-    if ( xc_domain_getfullinfo(xc_handle, ioctxt->domain, /* FIXME */ 0, 
-                               info, ctxt) )
+    if ( xc_domain_getinfo(xc_handle, ioctxt->domain, 1, info) )
     {
        xcio_error(ioctxt, "Could not get full domain info");
        return -1;
     }
 
+    if ( xc_domain_get_vcpu_context(xc_handle, ioctxt->domain, 0 /* XXX */, 
+                                   ctxt) )
+    {
+        xcio_error(ioctxt, "Could not get vcpu context");
+    }
+
     if ( (info->flags & 
           (DOMFLAGS_SHUTDOWN | (SHUTDOWN_suspend<<DOMFLAGS_SHUTDOWNSHIFT))) ==
          (DOMFLAGS_SHUTDOWN | (SHUTDOWN_suspend<<DOMFLAGS_SHUTDOWNSHIFT)) )
@@ -374,7 +379,7 @@ retry:
 
 int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
 {
-    xc_domaininfo_t info;
+    xc_dominfo_t info;
 
     int rc = 1, i, j, k, last_iter, iter = 0;
     unsigned long mfn;
@@ -444,13 +449,18 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
         xcio_perror(ioctxt, "Unable to mlock ctxt");
         return 1;
     }
-
-    if ( xc_domain_getfullinfo( xc_handle, domid, /* FIXME */ 0, 
-                                &info, &ctxt) )
+    
+    if ( xc_domain_getinfo(xc_handle, domid, 1, &info) )
     {
         xcio_error(ioctxt, "Could not get full domain info");
         goto out;
     }
+    if ( xc_domain_get_vcpu_context( xc_handle, domid, /* FIXME */ 0, 
+                                &ctxt) )
+    {
+        xcio_error(ioctxt, "Could not get vcpu context");
+        goto out;
+    }
     shared_info_frame = info.shared_info_frame;
 
     /* A cheesy test to see whether the domain contains valid state. */
@@ -459,7 +469,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
         goto out;
     }
     
-    nr_pfns = info.max_pages; 
+    nr_pfns = info.nr_pages; 
 
     /* cheesy sanity check */
     if ( nr_pfns > 1024*1024 ){
index 3260661acc968c1a68d4ee5b980cafb7c0217191..2d437080f130e11f3b2cb140a2005261b66a2a38 100644 (file)
@@ -440,17 +440,21 @@ xc_plan9_build(int xc_handle,
 
        op.cmd = DOM0_GETDOMAININFO;
        op.u.getdomaininfo.domain = (domid_t) domid;
-        op.u.getdomaininfo.exec_domain = 0;
-       op.u.getdomaininfo.ctxt = ctxt;
        if ((do_dom0_op(xc_handle, &op) < 0) ||
            ((u32) op.u.getdomaininfo.domain != domid)) {
                PERROR("Could not get info on domain");
                goto error_out;
        }
        DPRINTF(("xc_get_tot_pages returns %ld pages\n", tot_pages));
+       
+       if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
+       {
+           PERROR("Could not get vcpu context");
+           goto error_out;
+       }
 
        if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)
-           || (op.u.getdomaininfo.ctxt->pt_base != 0)) {
+           || (ctxt->pt_base != 0)) {
                ERROR("Domain is already constructed");
                goto error_out;
        }
index 15327ccdbb1de7eefbe4bdf25d92c6ef94e22f1e..39318bc4faf12d7838b656c1e5b2180d77748665 100644 (file)
@@ -173,17 +173,16 @@ long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
 {
     dom0_op_t op;
 
-    op.cmd = DOM0_GETDOMAININFO;
-    op.u.getdomaininfo.domain = (domid_t)domid;
-    op.u.getdomaininfo.exec_domain = (u16)vcpu;
-    op.u.getdomaininfo.ctxt = NULL;
-    if ( (do_dom0_op(xc_handle, &op) < 0) || 
-         ((u16)op.u.getdomaininfo.domain != domid) )
+    op.cmd = DOM0_GETVCPUCONTEXT;
+    op.u.getvcpucontext.domain = (domid_t)domid;
+    op.u.getvcpucontext.exec_domain = (u16)vcpu;
+    op.u.getvcpucontext.ctxt = NULL;
+    if ( (do_dom0_op(xc_handle, &op) < 0) )
     {
         PERROR("Could not get info on domain");
         return -1;
     }
-    return op.u.getdomaininfo.cpu_time;
+    return op.u.getvcpucontext.cpu_time;
 }
 
 
@@ -258,8 +257,6 @@ long xc_get_tot_pages(int xc_handle, u32 domid)
     dom0_op_t op;
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)domid;
-    op.u.getdomaininfo.exec_domain = 0;
-    op.u.getdomaininfo.ctxt = NULL;
     return (do_dom0_op(xc_handle, &op) < 0) ? 
         -1 : op.u.getdomaininfo.tot_pages;
 }
index 63efdd7cb9514a59a7901cfc6344ed12e531144e..ca051fab97bab62cfe46169ee6addcf5dc581359 100644 (file)
@@ -71,7 +71,7 @@ struct gdb_regs {
 #define FETCH_REGS(cpu) \
     if (!regs_valid[cpu]) \
     {                \
-       int retval = xc_domain_getfullinfo(xc_handle, domid, cpu, NULL, &ctxt[cpu]); \
+       int retval = xc_domain_get_vcpu_context(xc_handle, domid, cpu, &ctxt[cpu]); \
        if (retval) \
            goto error_out; \
        cr3[cpu] = ctxt[cpu].pt_base; /* physical address */ \
@@ -221,7 +221,6 @@ xc_waitdomain(int domain, int *status, int options)
 {
     dom0_op_t op;
     int retval;
-    vcpu_guest_context_t ctxt;
     struct timespec ts;
     ts.tv_sec = 0;
     ts.tv_nsec = 10*1000*1000;
@@ -234,12 +233,10 @@ xc_waitdomain(int domain, int *status, int options)
        }
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = domain;
-    op.u.getdomaininfo.exec_domain = 0;
-    op.u.getdomaininfo.ctxt = &ctxt;
  retry:
 
     retval = do_dom0_op(xc_handle, &op);
-    if (retval) {
+    if (retval || op.u.getdomaininfo.domain != domain) {
        printf("getdomaininfo failed\n");
        goto done;
     }
@@ -325,10 +322,8 @@ xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata)
     case PTRACE_ATTACH:
        op.cmd = DOM0_GETDOMAININFO;
        op.u.getdomaininfo.domain = domid;
-       op.u.getdomaininfo.exec_domain = 0;
-       op.u.getdomaininfo.ctxt = NULL;
        retval = do_dom0_op(xc_handle, &op);
-       if (retval) {
+       if (retval || op.u.getdomaininfo.domain != domid) {
            perror("dom0 op failed");
            goto error_out;
        }
index a89b783feeb398efe6c6be1ed3bb31909c3ff7fe..eeb8a57df6bb781b078e8e14bcfd2fd9da44851c 100644 (file)
@@ -543,14 +543,19 @@ int xc_vmx_build(int xc_handle,
 
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)domid;
-    op.u.getdomaininfo.exec_domain = 0;
-    op.u.getdomaininfo.ctxt = ctxt;
     if ( (do_dom0_op(xc_handle, &op) < 0) || 
          ((u16)op.u.getdomaininfo.domain != domid) )
     {
         PERROR("Could not get info on domain");
         goto error_out;
     }
+
+    if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
+    {
+        PERROR("Could not get vcpu context");
+        goto error_out;
+    }
+
     if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
          (ctxt->pt_base != 0) )
     {
index bae4a00caa5deab564df9fe6e6e270d1b45c8340..e4e3fe74ea6e6797ebf064de147395a9d75efc90 100644 (file)
@@ -299,9 +299,16 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
     case DOM0_GETDOMAININFO:
     { 
-        struct vcpu_guest_context *c;
-        struct domain            *d;
-        struct exec_domain       *ed;
+        struct domain             *d;
+        struct exec_domain        *ed;
+        u64 cpu_time = 0;
+        int vcpu_count = 0;
+        u32 processors = 0;
+        int flags = DOMFLAGS_PAUSED | DOMFLAGS_BLOCKED;
+
+#if MAX_VIRT_CPUS > 32
+#error "update processors field in GETDOMAININFO"
+#endif
 
         read_lock(&domlist_lock);
 
@@ -322,13 +329,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
 
         op->u.getdomaininfo.domain = d->id;
 
-        if ( (op->u.getdomaininfo.exec_domain >= MAX_VIRT_CPUS) ||
-             !d->exec_domain[op->u.getdomaininfo.exec_domain] )
-        {
-            ret = -EINVAL;
-            break;
-        }
-        
         memset(&op->u.getdomaininfo.vcpu_to_cpu, -1,
                sizeof(op->u.getdomaininfo.vcpu_to_cpu));
         memset(&op->u.getdomaininfo.cpumap, 0,
@@ -338,28 +338,86 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
             op->u.getdomaininfo.cpumap[ed->id]      = ed->cpumap;
         }
 
-        ed = d->exec_domain[op->u.getdomaininfo.exec_domain];
+        /* 
+         * - domain is marked as paused or blocked only if all its vcpus 
+         *   are paused or blocked 
+         * - domain is marked as running if any of its vcpus is running
+         */
+        
+        for_each_exec_domain(d, ed)  
+        { 
+            if (!((flags & DOMFLAGS_PAUSED) && test_bit(EDF_CTRLPAUSE, &ed->flags)))
+                flags &=  ~DOMFLAGS_PAUSED;
+            if (!((flags & DOMFLAGS_BLOCKED) && test_bit(EDF_BLOCKED, &ed->flags)))
+                flags &=  ~DOMFLAGS_BLOCKED;                
+            flags |= (test_bit(EDF_RUNNING,   &ed->flags) ? DOMFLAGS_RUNNING  : 0);
+
+            set_bit(ed->processor, &processors);
+            if ( ed->cpu_time > cpu_time )
+                cpu_time += ed->cpu_time;
+            vcpu_count++;
+        }
+        op->u.getdomaininfo.n_active_vcpus = vcpu_count;
+        op->u.getdomaininfo.cpu_time = cpu_time;
 
         op->u.getdomaininfo.flags =
             (test_bit( DF_DYING,      &d->flags)  ? DOMFLAGS_DYING    : 0) |
             (test_bit( DF_CRASHED,    &d->flags)  ? DOMFLAGS_CRASHED  : 0) |
             (test_bit( DF_SHUTDOWN,   &d->flags)  ? DOMFLAGS_SHUTDOWN : 0) |
-            (test_bit(EDF_CTRLPAUSE, &ed->flags) ? DOMFLAGS_PAUSED   : 0) |
-            (test_bit(EDF_BLOCKED,   &ed->flags) ? DOMFLAGS_BLOCKED  : 0) |
-            (test_bit(EDF_RUNNING,   &ed->flags) ? DOMFLAGS_RUNNING  : 0);
+            flags;
 
-        op->u.getdomaininfo.flags |= ed->processor << DOMFLAGS_CPUSHIFT;
         op->u.getdomaininfo.flags |= 
             d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT;
 
+        op->u.getdomaininfo.processors  = processors;
         op->u.getdomaininfo.tot_pages   = d->tot_pages;
         op->u.getdomaininfo.max_pages   = d->max_pages;
-        op->u.getdomaininfo.cpu_time    = ed->cpu_time;
         op->u.getdomaininfo.n_vcpu      = d->shared_info->n_vcpu;
         op->u.getdomaininfo.shared_info_frame = 
             __pa(d->shared_info) >> PAGE_SHIFT;
 
-        if ( op->u.getdomaininfo.ctxt != NULL )
+        if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )     
+            ret = -EINVAL;
+
+        put_domain(d);
+    }
+    break;
+
+    case DOM0_GETVCPUCONTEXT:
+    { 
+        struct vcpu_guest_context *c;
+        struct domain             *d;
+        struct exec_domain        *ed;
+        int active_index = 0; 
+        int exec_domain_index;
+
+        exec_domain_index = op->u.getvcpucontext.exec_domain;
+        d = find_domain_by_id(op->u.getvcpucontext.domain);
+
+        if ( d == NULL )
+        {
+            ret = -ESRCH;
+            break;
+        }
+
+        if ( (exec_domain_index >= MAX_VIRT_CPUS) )
+        {
+            ret = -EINVAL;
+            break;
+        }
+        
+        for_each_exec_domain(d, ed)
+        {
+            if ( exec_domain_index == active_index ) 
+            {
+                op->u.getvcpucontext.exec_domain = ed->id;
+                break;
+            }
+            active_index++;
+        }
+        op->u.getvcpucontext.cpu_time = ed->cpu_time;
+
+        if ( op->u.getvcpucontext.ctxt != NULL )
         {
             if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
             {
@@ -376,7 +434,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
             if ( ed != current )
                 exec_domain_unpause(ed);
 
-            if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
+            if ( copy_to_user(op->u.getvcpucontext.ctxt, c, sizeof(*c)) )
                 ret = -EINVAL;
 
             xfree(c);
index b07b68d7734c51bf0dd636a4f414d0637d3c3c43..59f0e6e0440486253e0527fefd739d97dc8a932e 100644 (file)
@@ -70,7 +70,7 @@ typedef struct {
 typedef struct {
     /* IN variables. */
     domid_t  domain;                  /* NB. IN/OUT variable. */
-    u16      exec_domain;
+    u16      n_active_vcpus;          /* # of vcpus currently active */
     /* OUT variables. */
 #define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
 #define DOMFLAGS_CRASHED   (1<<1) /* Crashed domain; frozen for postmortem.  */
@@ -83,7 +83,7 @@ typedef struct {
 #define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code.  */
 #define DOMFLAGS_SHUTDOWNSHIFT 16
     u32      flags;
-    vcpu_guest_context_t *ctxt;   /* NB. IN/OUT variable. */
+    u32      processors;       
     memory_t tot_pages;
     memory_t max_pages;
     memory_t shared_info_frame;       /* MFN of shared_info struct */
@@ -345,6 +345,15 @@ typedef struct {
     u16     allow_access;             /* allow or deny access to range? */
 } dom0_ioport_permission_t;
 
+#define DOM0_GETVCPUCONTEXT      37
+typedef struct {
+    domid_t domain;                   /* domain to be affected */
+    u16     exec_domain;              /* NB. IN: nth active cpu / OUT: actual cpu # */
+    vcpu_guest_context_t *ctxt;       /* NB. IN/OUT variable. */
+    u64     cpu_time;                 
+} dom0_getvcpucontext_t;
+
+
 typedef struct {
     u32 cmd;
     u32 interface_version; /* DOM0_INTERFACE_VERSION */
@@ -376,6 +385,7 @@ typedef struct {
         dom0_perfccontrol_t      perfccontrol;
         dom0_microcode_t         microcode;
         dom0_ioport_permission_t ioport_permission;
+        dom0_getvcpucontext_t    getvcpucontext;
     } u;
 } dom0_op_t;